home *** CD-ROM | disk | FTP | other *** search
/ Just Call Me Internet / Just Call Me Internet.iso / prog / atari / c / nos042_s / main.c < prev    next >
C/C++ Source or Header  |  1994-09-16  |  17KB  |  801 lines

  1. /* Main-level NOS program:
  2.  *  initialization
  3.  *  keyboard processing
  4.  *  generic user commands
  5.  *
  6.  * Copyright 1991 Phil Karn, KA9Q
  7.  */
  8.  
  9. /****************************************************************************
  10. *    $Id: main.c 1.5 94/01/04 14:09:37 ROOT_DOS Exp $
  11. *    14 Jul 93    1.4        GT    Banner changes.                                    *
  12. *    07 Nov 93    1.5        GT    Prompt global.                                    *
  13. *
  14. *    ATARI Version by David Nash - dnash@chaos.demon.co.uk
  15. *
  16. *  __stdargs dosourceb, domore
  17. *  dosource, dosurceb call do_source to avoid reg/std call sequecne problems
  18. *
  19. ****************************************************************************/
  20.  
  21. #include <stdio.h>
  22. #include <time.h>
  23. #if    defined(__TURBOC__) && defined(MSDOS)
  24. #include <io.h>
  25. #include <conio.h>
  26. #endif
  27. #include "global.h"
  28. #ifdef    ANSIPROTO
  29. #include <stdarg.h>
  30. #endif
  31.  
  32. #ifdef   ATARI
  33. #include <unistd.h>
  34. #endif
  35.  
  36. #include "mbuf.h"
  37. #include "timer.h"
  38. #include "proc.h"
  39. #include "iface.h"
  40. #include "ip.h"
  41. #include "tcp.h"
  42. #include "udp.h"
  43. #include "ax25.h"
  44. #include "kiss.h"
  45. #include "enet.h"
  46. #include "netrom.h"
  47. #include "ftpcli.h"
  48. #include "telnet.h"
  49. #include "tty.h"
  50. #include "session.h"
  51. #include "hardware.h"
  52. #include "usock.h"
  53. #include "socket.h"
  54. #include "cmdparse.h"
  55. #include "commands.h"
  56. #include "daemon.h"
  57. #include "devparam.h"
  58. #include "domain.h"
  59. #include "files.h"
  60. #include "main.h"
  61. #include "remote.h"
  62. #include "trace.h"
  63.  
  64. extern struct cmds far Cmds[], Startcmds[],Stopcmds[],Attab[];
  65.  
  66. #ifdef MSDOS
  67. int Escape = 324;    /* MSDOS escape character is F10 */
  68. #else
  69. #ifdef ATARI
  70. int Escape = 0x44;    /* default excape character is F10 */
  71. #else
  72. char Escape = 0x1d;    /* default escape character is ^] */
  73. #endif
  74. #endif
  75.  
  76. char Badhost[] = "Unknown host %s\n";
  77. char *Hostname;
  78. char Nospace[] = "No space!!\n";    /* Generic malloc fail message */
  79. struct proc *Cmdpp;
  80. struct proc *Display;
  81. int main_exit = FALSE;            /* from main program (flag) */
  82.  
  83. #ifndef ATARI
  84. char Prompt[] = "net> ";
  85. #else
  86. char Prompt[] = "\x08\x08NET > ";
  87. #endif
  88. static FILE *Logfp;
  89. static time_t StartTime;        /* time that NOS was started */
  90. static int Verbose;
  91.  
  92. static char banner1[] = "Based on KA9Q NOS by Phil Karn - %s\n";
  93. static char banner2[] = "Copyright 1991 Phil Karn.  ";
  94. static char banner3[] = "Parts copyright 1992, 1993 Demon Internet & Members\n\n";
  95. static char banner4[] = "Support: mail internet@demon.net or phone 081 343 3881\n";
  96.  
  97. int main(int argc, char *argv[])
  98. {
  99.     char *inbuf,*intmp;
  100.     FILE *fp;
  101.     struct daemon *tp;
  102.     struct mbuf *bp;
  103.     int c;
  104.     int rootset = 0;
  105.  
  106.     StartTime = time(&StartTime);
  107.  
  108.     while((c = getopt(argc, argv, "s:d:bv")) != EOF){
  109.         switch(c){
  110.         case 's':    /* Number of sockets */
  111.             Nusock = atoi(optarg);
  112.             break;
  113.         case 'd':    /* Root directory for various files */
  114.             rootset = 1;
  115.             initroot(optarg);
  116.             break;
  117.         case 'b':    /* Use BIOS for screen output */
  118. #ifdef    __TURBOC__
  119.             directvideo = 0;
  120. #endif
  121.             break;
  122.         case 'v':
  123.             Verbose = 1;
  124.             break;
  125.         case '?':                                        /* illegal option found            */
  126.             printf("usage: %s [-s num] [-d dir] [-v] [startup] \n", argv[0]);
  127.             printf("where num = number of sockets, default=%d \n", Nusock);
  128.             printf("      dir = root directory for nos, default=\\ \n");
  129.             printf("      -v = verbose flag \n");
  130.             printf("      startup = startup file, default=%s\n", Startup);
  131.  
  132.             return -1;                           /* give up and exit                 */             
  133.         }
  134.     }
  135.  
  136.     if(!rootset) {                                        /* set route from env - DFN     */
  137.         char *root;
  138.  
  139.         if ((root = getenv("NOS_ROOT")))
  140.             initroot(root);
  141.         else
  142.             initroot("\\");
  143.     }
  144.  
  145.     kinit();
  146.     ipinit();
  147.     ioinit();
  148.     sockinit();
  149.     Cmdpp = mainproc("cmdintrp");
  150.  
  151.     Sessions = (struct session *)callocw(Nsessions, sizeof(struct session));
  152.     Command  = Lastcurr = newsession("command interpreter", COMMAND);
  153.     Display  = newproc("display", 250, display, 0, NULLCHAR, NULL, 0);
  154.  
  155.     tprintf("\033E");                                /* clear the screen               */
  156.     tprintf("%s %s %s\n\n", atari_ver1, atari_ver2, atari_ver3);
  157.     tprintf(banner1, Version);
  158.     tprintf(banner2);
  159.     tprintf(banner3);
  160. /* 
  161.     tprintf(banner4);
  162. */
  163.    log(-1,"Load address %X \n", main);    
  164.     rflush();
  165.  
  166.     /* Start background Daemons */
  167.  
  168.     for (tp = Daemons; ; tp++) {
  169.         if (tp->name == NULLCHAR)
  170.             break;
  171.         newproc(tp->name, tp->stksize, tp->fp, 0, NULLCHAR, NULL, 0);
  172.     }
  173.  
  174.     if (optind < argc) {
  175.         /* Read startup file named on command line */
  176.         if ((fp = fopen(argv[optind], READ_TEXT)) == NULLFILE)
  177.             tprintf("Can't read config file %s: %s\n",
  178.              argv[optind],strerror(errno));
  179.     } else {
  180.         fp = fopen(Startup,READ_TEXT);
  181.     }
  182.     if(fp != NULLFILE){
  183.         inbuf = mallocw(BUFSIZ);
  184.         intmp = mallocw(BUFSIZ);
  185.         while(fgets(inbuf,BUFSIZ,fp) != NULLCHAR){
  186.             strcpy(intmp,inbuf);
  187.             if(Verbose)
  188.                 tprintf("%s",intmp);
  189.             if(cmdparse(Cmds,inbuf,NULL) != 0){
  190.                 tprintf("input line: %s",intmp);
  191.             }
  192.         }
  193.         fclose(fp);
  194.         free(inbuf);
  195.         free(intmp);
  196.     }
  197.     /* Now loop forever, processing commands */
  198.     for( ; ; ) {
  199.         tprintf(Prompt);
  200.         usflush(Command->output);
  201.         if (recv_mbuf(Command->input, &bp, 0, NULLCHAR, 0) != -1) {
  202.             (void)cmdparse(Cmds, bp->data, Lastcurr);
  203.             free_p(bp);
  204.         }
  205.     }
  206.     return 0;
  207. }
  208.  
  209.  
  210. /*
  211.     keyboard - Keyboard input process
  212. */
  213.  
  214. void keyboard(int i, void *v1, void *v2)
  215. {
  216.     int c;
  217.     struct mbuf *bp;
  218.  
  219.     Current->cur_pos = 0;
  220.  
  221.     /* Keyboard process loop */
  222.  
  223.     for( ; ; ) {
  224.         c = kbread();
  225.         if (c == -2 && Current != Command) {
  226.  
  227.             /* Save current tty mode and set cooked */
  228. #ifndef ATARI            
  229.             swapscreen(Current,Command);
  230. #else
  231.             alert(Display, 1);
  232. #endif            
  233.             Lastcurr = Current;
  234.             Current = Command;
  235.         }
  236.         
  237.         Current->row = MOREROWS;
  238.         psignal(&Current->row, 1);
  239.  
  240.         if(c >= 0) {
  241.             /* If the screen driver was in morewait state, this char
  242.              * has woken him up. Toss it so it doesn't also get taken
  243.              * as normal input. If the char was a command escape,
  244.              * however, it will be accepted; this gives the user
  245.              * a way out of lengthy output.
  246.              */
  247.             if (!Current->morewait && (bp = ttydriv(Current,c)) != NULLBUF) {
  248.                 send_mbuf(Current->input, bp, 0, NULLCHAR, 0);
  249.                 Current->cur_pos = 0;
  250.             }
  251.         }
  252.     }
  253. }
  254.  
  255.  
  256. /*
  257.     dodelete - Delete a file
  258. */
  259.  
  260. int dodelete(int argc, char *argv[], void *p)
  261. {
  262.     int i;
  263.  
  264.     for(i = 1; i < argc; i++) {
  265.         if(unlink(argv[i]) == -1) {
  266.             tprintf("Can't delete %s: %s\n",
  267.             argv[i],strerror(errno));
  268.         }
  269.     }
  270.     return 0;
  271. }
  272.  
  273.  
  274. int
  275. dorename(argc,argv,p)
  276. int argc;
  277. char *argv[];
  278. void *p;
  279. {
  280.     if(rename(argv[1],argv[2]) == -1)
  281.         tprintf("Can't rename: %s\n",strerror(errno));
  282.     return 0;
  283. }
  284. int
  285. doexit(argc,argv,p)
  286. int argc;
  287. char *argv[];
  288. void *p;
  289. {
  290.     int i;
  291.     time_t StopTime;
  292.  
  293.     StopTime = time(&StopTime);
  294.     main_exit = TRUE;    /* let everyone know we're out of here */
  295.     reset_all();
  296.     if(Dfile_updater != NULLPROC)
  297.         alert(Dfile_updater,0);    /* don't wait for timeout */
  298.     for(i=0;i<100;i++)
  299.         pwait(NULL);    /* Allow tasks to complete */
  300.     shuttrace();
  301.     log(-1,"NOS was stopped at %s", ctime(&StopTime));
  302.     if(Logfp){
  303.         fclose(Logfp);
  304.         Logfp = NULLFILE;
  305.     }
  306.     iostop();
  307.     exit(0);
  308.     return 0;    /* To satisfy lint */
  309. }
  310. int
  311. dohostname(argc,argv,p)
  312. int argc;
  313. char *argv[];
  314. void *p;
  315. {
  316.     if(argc < 2)
  317.         tprintf("%s\n",Hostname);
  318.     else {
  319.         struct iface *ifp;
  320.         char *name;
  321.  
  322.         if((ifp = if_lookup(argv[1])) != NULLIF){
  323.             if((name = resolve_a(ifp->addr, FALSE)) == NULLCHAR){
  324.                 tprintf("Interface address not resolved\n");
  325.                 return 1;
  326.             } else {
  327.                 if(Hostname != NULLCHAR)
  328.                     free(Hostname);
  329.                 Hostname = name;
  330.  
  331.                 /* remove trailing dot */
  332.                 if ( Hostname[strlen(Hostname)] == '.' ) {
  333.                     Hostname[strlen(Hostname)] = '\0';
  334.                 }
  335.                 tprintf("Hostname set to %s\n", name );
  336.             }
  337.         } else {
  338.             if(Hostname != NULLCHAR)
  339.                 free(Hostname);
  340.             Hostname = strdup(argv[1]);
  341.         }
  342.     }
  343.     return 0;
  344. }
  345. int
  346. dolog(argc,argv,p)
  347. int argc;
  348. char *argv[];
  349. void *p;
  350. {
  351.     static char *logname;
  352.  
  353.     if(argc < 2){
  354.         if(Logfp)
  355.             tprintf("Logging to %s\n",logname);
  356.         else
  357.             tprintf("Logging off\n");
  358.         return 0;
  359.     }
  360.     if(Logfp){
  361.         log(-1,"NOS log closed");
  362.         fclose(Logfp);
  363.         Logfp = NULLFILE;
  364.         free(logname);
  365.         logname = NULLCHAR;
  366.     }
  367.     if(strcmp(argv[1],"stop") != 0){
  368.         logname = strdup(argv[1]);
  369.         Logfp = fopen(logname,APPEND_TEXT);
  370.         log(-1,"NOS was started at %s", ctime(&StartTime));
  371. #ifdef ATARI
  372.         log(-1, "NOS Load address: %x ", main);
  373. #endif        
  374. #ifdef MSDOS
  375.         log(-1,"NOS load information: CS=0x%04x DS=0x%04x", _CS, _DS);
  376. #endif
  377.     }
  378.     return 0;
  379. }
  380.  
  381. /*
  382.     dosource - stub function for do_source with __regargs linkage
  383. */
  384.  
  385. int dosource(int argc, char *argv[], void *p)
  386. {
  387.     return do_source(argc, argv, p);
  388. }
  389.  
  390. /*
  391.     dosourceb - stub function for do_source with _-stdargs linkage
  392. */
  393.  
  394. int __stdargs dosourceb(int argc, char *argv[], void *p)
  395. {
  396.     return do_source(argc, argv, p);
  397. }
  398.  
  399. /*
  400.     do_source - replaces dosource in pc ka9q, called via stub functions to
  401.                 fixup the linkage.
  402. */
  403.                 
  404. static int do_source(int argc, char *argv[], void *p)
  405. {
  406.     int linenum = 0;
  407.     char *inbuf,*intmp, *p1, *p2;
  408.     FILE *fp;
  409.  
  410.     /* Read command source file */
  411.     if((fp = fopen(argv[1],READ_TEXT)) == NULLFILE){
  412.         tprintf("Can't read %s: %s\n",argv[1],strerror(errno));
  413.         return 1;
  414.     }
  415.  
  416.     p1 = inbuf = malloc(BUFSIZ);
  417.     p2 = intmp = malloc(BUFSIZ);
  418.     while(fgets(inbuf,BUFSIZ,fp) != NULLCHAR){
  419.         strcpy(intmp,inbuf);
  420.         linenum++;
  421.         if(Verbose)
  422.             tprintf("%s",intmp);
  423.         if(cmdparse(Cmds,inbuf,NULL) != 0){
  424.             tprintf("*** file \"%s\", line %d: %s\n",
  425.                 argv[1],linenum,intmp);
  426.         }
  427.     }
  428.     fclose(fp);
  429.     free(p1);
  430.     free(p2);
  431.     return 0;
  432. }
  433.  
  434. int
  435. dohelp(argc,argv,p)
  436. int argc;
  437. char *argv[];
  438. void *p;
  439. {
  440.     register struct cmds *cmdp;
  441.     int i;
  442.     char buf[66];
  443.  
  444.     tprintf(banner1, Version);
  445.     tprintf(banner2);
  446.     tprintf(banner3);
  447.     tprintf(banner4);
  448.     tprintf("Main commands:\n");
  449.     memset(buf,' ',sizeof(buf));
  450.     buf[64] = '\n';
  451.     buf[65] = '\0';
  452.     for(i=0,cmdp = Cmds;cmdp->name != NULL;cmdp++,i = (i+1)%4){
  453.         strncpy(&buf[i*16],cmdp->name,strlen(cmdp->name));
  454.         if(i == 3){
  455.             tprintf(buf);
  456.             memset(buf,' ',sizeof(buf));
  457.             buf[64] = '\n';
  458.             buf[65] = '\0';
  459.         }
  460.     }
  461.     if(i != 0)
  462.         tprintf(buf);
  463.     return 0;
  464. }
  465. /* Attach an interface
  466.  * Syntax: attach <hw type> <I/O address> <vector> <mode> <label> <bufsize> [<speed>]
  467.  */
  468. int
  469. doattach(argc,argv,p)
  470. int argc;
  471. char *argv[];
  472. void *p;
  473. {
  474.     return subcmd(Attab,argc,argv,p);
  475. }
  476. /* Manipulate I/O device parameters */
  477. int
  478. doparam(argc,argv,p)
  479. int argc;
  480. char *argv[];
  481. void *p;
  482. {
  483.     register struct iface *ifp;
  484.     int param,set;
  485.     int32 val;
  486.  
  487.     if((ifp = if_lookup(argv[1])) == NULLIF){
  488.         tprintf("Interface \"%s\" unknown\n",argv[1]);
  489.         return 1;
  490.     }
  491.     if(ifp->ioctl == NULL){
  492.         tprintf("Not supported\n");
  493.         return 1;
  494.     }
  495.     if(argc < 3){
  496.         for(param=1;param<=16;param++){
  497.             val = (*ifp->ioctl)(ifp,param,FALSE,0L);
  498.             if(val != -1)
  499.                 tprintf("%s: %ld\n",parmname(param),val);
  500.         }
  501.         return 0;
  502.     }
  503.     param = devparam(argv[2]);
  504.     if(param == -1){
  505.         tprintf("Unknown parameter %s\n",argv[2]);
  506.         return 1;
  507.     }
  508.     if(argc < 4){
  509.         set = FALSE;
  510.         val = 0L;
  511.     } else {
  512.         set = TRUE;
  513.         val = atol(argv[3]);
  514.     }
  515.     val = (*ifp->ioctl)(ifp,param,set,val);
  516.     if(val == -1){
  517.         tprintf("Parameter %s not supported\n",argv[2]);
  518.     } else {
  519.         tprintf("%s: %ld\n",parmname(param),val);
  520.     }
  521.     return 0;
  522. }
  523.  
  524. /* Display or set IP interface control flags */
  525. int
  526. domode(argc,argv,p)
  527. int argc;
  528. char *argv[];
  529. void *p;
  530. {
  531.     register struct iface *ifp;
  532.  
  533.     if((ifp = if_lookup(argv[1])) == NULLIF){
  534.         tprintf("Interface \"%s\" unknown\n",argv[1]);
  535.         return 1;
  536.     }
  537.     if(argc < 3){
  538.         tprintf("%s: %s\n",ifp->name,
  539.          (ifp->flags & CONNECT_MODE) ? "VC mode" : "Datagram mode");
  540.         return 0;
  541.     }
  542.     switch(argv[2][0]){
  543.     case 'v':
  544.     case 'c':
  545.     case 'V':
  546.     case 'C':
  547.         ifp->flags = CONNECT_MODE;
  548.         break;
  549.     case 'd':
  550.     case 'D':
  551.         ifp->flags = DATAGRAM_MODE;
  552.         break;
  553.     default:
  554.         tprintf("Usage: %s [vc | datagram]\n",argv[0]);
  555.         return 1;
  556.     }
  557.     return 0;
  558. }
  559.  
  560. int
  561. doescape(argc,argv,p)
  562. int argc;
  563. char *argv[];
  564. void *p;
  565. {
  566.     if(argc < 2)
  567.         tprintf("%d\n",Escape);
  568.     else if (strlen(argv[1]) == 1)
  569.         Escape = *argv[1];
  570.     else Escape = atoi(argv[1]);
  571.     return 0;
  572. }
  573.  
  574. /* Generate system command packet. Synopsis:
  575.  * remote [-p port#] [-k key] [-a hostname] <hostname> reset|exit|kickme
  576.  */
  577. int
  578. doremote(argc,argv,p)
  579. int argc;
  580. char *argv[];
  581. void *p;
  582. {
  583.     struct sockaddr_in fsock;
  584.     int s,c;
  585.     char *data,x;
  586.     int16 port,len;
  587.     char *key = NULLCHAR;
  588.     int klen;
  589.     int32 addr = 0;
  590.     char *cmd,*host;
  591.  
  592.     port = IPPORT_REMOTE;    /* Set default */
  593.     optind = 1;        /* reinit getopt() */
  594.     while((c = getopt(argc,argv,"a:p:k:s:")) != EOF){
  595.         switch(c){
  596.         case 'a':
  597.             addr = resolve(optarg);
  598.             break;
  599.         case 'p':
  600.             port = atoi(optarg);
  601.             break;
  602.         case 'k':
  603.             key = optarg;
  604.             klen = strlen(key);
  605.             break;
  606.         case 's':
  607.             Rempass = strdup(optarg);
  608.             return 0;    /* Only set local password */
  609.         }
  610.     }
  611.     if(optind > argc - 2){
  612.         tprintf("Insufficient args\n");
  613.         return -1;
  614.     }
  615.     host = argv[optind++];
  616.     cmd = argv[optind];
  617.     if((s = socket(AF_INET,SOCK_DGRAM,0)) == -1){
  618.         tprintf("socket failed\n");
  619.         return 1;
  620.     }
  621.     len = 1;
  622.     /* Did the user include a password or kickme target? */
  623.     if(addr != 0)
  624.         len += sizeof(int32);
  625.  
  626.     if(key != NULLCHAR)
  627.         len += klen;
  628.  
  629.     if(len == 1)
  630.         data = &x;
  631.     else
  632.         data = mallocw(len);
  633.  
  634.     fsock.sin_family = AF_INET;
  635.     fsock.sin_addr.s_addr = resolve(host);
  636.     fsock.sin_port = port;
  637.  
  638.     switch(cmd[0]){
  639.     case 'r':
  640.         data[0] = SYS_RESET;
  641.         if(key != NULLCHAR)
  642.             strncpy(&data[1],key,klen);
  643.         break;
  644.     case 'e':
  645.         data[0] = SYS_EXIT;
  646.         if(key != NULLCHAR)
  647.             strncpy(&data[1],key,klen);
  648.         break;
  649.     case 'k':
  650.         data[0] = KICK_ME;
  651.         if(addr != 0)
  652.             put32(&data[1],addr);
  653.         break;
  654.     default:
  655.         tprintf("Unknown command %s\n",cmd);
  656.         goto cleanup;
  657.     }
  658.     /* Form the command packet and send it */
  659.     if(sendto(s,data,len,0,(char *)&fsock,sizeof(fsock)) == -1){
  660.         tprintf("sendto failed: %s\n",strerror(errno));
  661.         goto cleanup;
  662.     }
  663. cleanup:
  664.     if(data != &x)
  665.         free(data);
  666.     close_s(s);
  667.     return 0;
  668. }
  669. int __stdargs domore(argc,argv,p)
  670. int argc;
  671. char *argv[];
  672. void *p;
  673. {
  674.     struct session *sp;
  675.     FILE *fp;
  676.     char buf[81];
  677.     int row;
  678.  
  679.     if((sp = newsession(argv[1],MORE)) == NULLSESSION){
  680.         return -1;
  681.     }
  682.     /* Put tty into raw mode so single-char responses will work */
  683.     sp->ttystate.echo = sp->ttystate.edit = 0;
  684.     if((fp = fopen(argv[1],READ_TEXT)) == NULLFILE){
  685.         tprintf("Can't read %s\n",argv[1]);
  686.         keywait(NULLCHAR,1);
  687.         freesession(sp);
  688.         return 1;
  689.     }
  690.     row = MOREROWS;
  691.     while(fgets(buf,sizeof(buf),fp),!feof(fp)){
  692.         tprintf("%s",buf);
  693.         if(--row == 0){
  694.             row = keywait("--More--",0);
  695.             switch(row){
  696.             case -1:
  697.             case 'q':
  698.             case 'Q':
  699.                 goto done;
  700.             case '\n':
  701.             case '\r':
  702.                 row = 1;
  703.                 break;
  704.             case ' ':
  705.             default:
  706.                 row = MOREROWS;
  707.             }
  708.         }
  709.     }
  710. done:    fclose(fp);
  711.     keywait(NULLCHAR,1);
  712.     freesession(sp);
  713.     return 0;
  714. }
  715. /* No-op command */
  716. int
  717. donothing(argc,argv,p)
  718. int argc;
  719. char *argv[];
  720. void *p;
  721. {
  722.     return 0;
  723. }
  724.  
  725. /* Log messages of the form
  726.  * Tue Jan 31 00:00:00 1987 44.64.0.7:1003 open FTP
  727.  */
  728. #if    defined(ANSIPROTO)
  729. void
  730. log(int s,char *fmt, ...)
  731. {
  732.     va_list ap;
  733.     char *cp;
  734.     long t;
  735.     int i;
  736.     struct sockaddr fsocket;
  737. #if defined(MSDOS) || defined(ATARI)
  738.     int fd;
  739. #endif
  740.  
  741.     if(Logfp == NULLFILE)
  742.         return;
  743.  
  744.     time(&t);
  745.     cp = ctime(&t);
  746.     rip(cp);
  747.     i = SOCKSIZE;
  748.     fprintf(Logfp,"%s",cp);
  749.     if(getpeername(s,(char *)&fsocket,&i) != -1)
  750.         fprintf(Logfp," %s",psocket(&fsocket));
  751.  
  752.     fprintf(Logfp," - ");
  753.     va_start(ap,fmt);
  754.     vfprintf(Logfp,fmt,ap);
  755.     va_end(ap);
  756.     fprintf(Logfp,"\n");
  757.     fflush(Logfp);
  758. #if defined(MSDOS) || defined(ATARI)
  759.     /* MS-DOS doesn't really flush files until they're closed */
  760.     fd = fileno(Logfp);
  761.     if((fd = dup(fd)) != -1)
  762.         close(fd);
  763. #endif
  764. }
  765. #else
  766. /*VARARGS2*/
  767. void
  768. log(s,fmt,arg1,arg2,arg3,arg4,arg5)
  769. int s;
  770. char *fmt;
  771. int arg1,arg2,arg3,arg4,arg5;
  772. {
  773.     char *cp;
  774.     long t;
  775.     int fd,i;
  776.     struct sockaddr fsocket;
  777.  
  778.     if(Logfp == NULLFILE)
  779.         return;
  780.     time(&t);
  781.     cp = ctime(&t);
  782.     rip(cp);
  783.     i = SOCKSIZE;
  784.     fprintf(Logfp,"%s",cp);
  785.     if(getpeername(s,(char *)&fsocket,&i) != -1)
  786.         fprintf(Logfp," %s",psocket(&fsocket));
  787.  
  788.     fprintf(Logfp," - ");
  789.     fprintf(Logfp,fmt,arg1,arg2,arg3,arg4,arg5);
  790.     fprintf(Logfp,"\n");
  791.     fflush(Logfp);
  792. #ifdef    MSDOS
  793.     /* MS-DOS doesn't really flush files until they're closed */
  794.     fd = fileno(Logfp);
  795.     if((fd = dup(fd)) != -1)
  796.         close(fd);
  797. #endif
  798. }
  799. #endif
  800.  
  801.